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.

2087 lines
48 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. unidrv.c
  5. Abstract:
  6. This file handles Unidrv specific UI options
  7. Environment:
  8. Win32 subsystem, DriverUI module, user mode
  9. Revision History:
  10. 12/17/96 -amandan-
  11. Created it.
  12. --*/
  13. #include "precomp.h"
  14. #include <ntverp.h>
  15. DWORD DwCollectFontCart(PUIDATA, PWSTR, DWORD);
  16. PWSTR PwstrGetFontCartSelections(HANDLE, HANDLE, PDWORD);
  17. INT IGetCurrentFontCartIndex(POPTTYPE, PWSTR);
  18. PWSTR PwstrGetFontCartName( PCOMMONINFO, PUIINFO, FONTCART *, DWORD, HANDLE);
  19. DWORD DwGetExternalCartridges(HANDLE, HANDLE, PWSTR *);
  20. DWORD
  21. _DwEnumPersonalities(
  22. PCOMMONINFO pci,
  23. PWSTR pwstrOutput
  24. )
  25. /*++
  26. Routine Description:
  27. Enumerate the list of supported printer description languages
  28. Arguments:
  29. pci - Points to common printer info
  30. pwstrOutput - Points to output buffer
  31. Return Value:
  32. Number of personalities supported
  33. GDI_ERROR if there is an error
  34. --*/
  35. {
  36. PWSTR pwstrPersonality = PGetReadOnlyDisplayName(pci,
  37. pci->pUIInfo->loPersonality);
  38. if (pwstrPersonality == NULL)
  39. {
  40. SetLastError(ERROR_NOT_SUPPORTED);
  41. return GDI_ERROR;
  42. }
  43. if (pwstrOutput)
  44. CopyString(pwstrOutput, pwstrPersonality, CCHLANGNAME);
  45. return 1;
  46. }
  47. DWORD
  48. _DwGetFontCap(
  49. PUIINFO pUIInfo
  50. )
  51. /*++
  52. Routine Description:
  53. Get the font capability for DrvDeviceCapabilites (DC_TRUETYPE)
  54. Arguments:
  55. pUIInfo - Pointer to UIINFO
  56. Return Value:
  57. DWORD describing the TrueType cap for Unidrv
  58. --*/
  59. {
  60. DWORD dwRet;
  61. if (pUIInfo->dwFlags & FLAG_FONT_DOWNLOADABLE)
  62. dwRet = (DWORD) (DCTT_BITMAP | DCTT_DOWNLOAD);
  63. else
  64. dwRet = DCTT_BITMAP;
  65. return dwRet;
  66. }
  67. DWORD
  68. _DwGetOrientationAngle(
  69. PUIINFO pUIInfo,
  70. PDEVMODE pdm
  71. )
  72. /*++
  73. Routine Description:
  74. Get the orienation angle requested by DrvDeviceCapabilities(DC_ORIENTATION)
  75. Arguments:
  76. pUIInfo - Pointer to UIINFO
  77. pdm - Pointer to DEVMODE
  78. Return Value:
  79. The angle (90 or 270 or landscape rotation)
  80. Note:
  81. --*/
  82. {
  83. DWORD dwRet = GDI_ERROR;
  84. DWORD dwIndex;
  85. PORIENTATION pOrientation;
  86. PFEATURE pFeature;
  87. if (pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_ORIENTATION))
  88. {
  89. //
  90. // Currently Unidrv only allows at most 2 options for feature "Orientation".
  91. // So when we see the first non-Portrait option, that's the Landscape option
  92. // we can use to get the orientation angle.
  93. //
  94. pOrientation = (PORIENTATION)PGetIndexedOption(pUIInfo, pFeature, 0);
  95. for (dwIndex = 0; dwIndex < pFeature->Options.dwCount; dwIndex++, pOrientation++)
  96. {
  97. if (pOrientation->dwRotationAngle == ROTATE_90)
  98. {
  99. return 90;
  100. }
  101. else if (pOrientation->dwRotationAngle == ROTATE_270)
  102. {
  103. return 270;
  104. }
  105. }
  106. //
  107. // If we are here, it means the printer doesn't support Landscape
  108. // orientation, so we return angle 0.
  109. //
  110. return 0;
  111. }
  112. return dwRet;
  113. }
  114. BOOL
  115. _BPackOrientationItem(
  116. IN OUT PUIDATA pUiData
  117. )
  118. /*++
  119. Routine Description:
  120. Pack the orientation feature for Doc property sheet
  121. Arguments:
  122. pUiData - Points to UIDATA structure
  123. Return Value:
  124. TRUE for success and FALSE for failure
  125. --*/
  126. {
  127. return BPackItemPrinterFeature(
  128. pUiData,
  129. GET_PREDEFINED_FEATURE(pUiData->ci.pUIInfo, GID_ORIENTATION),
  130. TVITEM_LEVEL1,
  131. DMPUB_ORIENTATION,
  132. (ULONG_PTR)ORIENTATION_ITEM,
  133. HELP_INDEX_ORIENTATION);
  134. }
  135. BOOL
  136. BPackHalftoneFeature(
  137. IN OUT PUIDATA pUiData
  138. )
  139. /*++
  140. Routine Description:
  141. Pack the halfone feature
  142. Arguments:
  143. pUiData - Points to UIDATA structure
  144. Return Value:
  145. TRUE for success and FALSE for failure
  146. Note:
  147. --*/
  148. {
  149. return BPackItemPrinterFeature(
  150. pUiData,
  151. GET_PREDEFINED_FEATURE(pUiData->ci.pUIInfo, GID_HALFTONING),
  152. TVITEM_LEVEL1,
  153. DMPUB_NONE,
  154. (ULONG_PTR)HALFTONING_ITEM,
  155. HELP_INDEX_HALFTONING_TYPE);
  156. }
  157. BOOL
  158. BPackColorModeFeature(
  159. IN OUT PUIDATA pUiData
  160. )
  161. /*++
  162. Routine Description:
  163. Pack Color mode feature
  164. Arguments:
  165. pUiData - Points to UIDATA structure
  166. Return Value:
  167. TRUE for success and FALSE for failure
  168. --*/
  169. {
  170. return BPackItemPrinterFeature(
  171. pUiData,
  172. GET_PREDEFINED_FEATURE(pUiData->ci.pUIInfo, GID_COLORMODE),
  173. TVITEM_LEVEL1,
  174. DMPUB_NONE,
  175. (ULONG_PTR)COLORMODE_ITEM,
  176. HELP_INDEX_COLORMODE_TYPE);
  177. }
  178. BOOL
  179. BPackQualityFeature(
  180. IN OUT PUIDATA pUiData
  181. )
  182. /*++
  183. Routine Description:
  184. Pack Quality Macro feature
  185. Arguments:
  186. pUiData - Points to UIDATA structure
  187. Return Value:
  188. TRUE for success and FALSE for failure
  189. --*/
  190. {
  191. #ifndef WINNT_40
  192. INT i, iSelection, iParamCount = 0;
  193. PUIINFO pUIInfo = pUiData->ci.pUIInfo;
  194. POPTPARAM pParam;
  195. PEXTCHKBOX pExtCheckbox;
  196. INT Quality[MAX_QUALITY_SETTINGS];
  197. memset(Quality, -1, sizeof(INT)*MAX_QUALITY_SETTINGS);
  198. if (pUIInfo->liDraftQualitySettings != END_OF_LIST )
  199. {
  200. Quality[QS_DRAFT] = QS_DRAFT;
  201. iParamCount++;
  202. }
  203. if ( pUIInfo->liBetterQualitySettings != END_OF_LIST )
  204. {
  205. Quality[QS_BETTER] = QS_BETTER;
  206. iParamCount++;
  207. }
  208. if ( pUIInfo->liBestQualitySettings != END_OF_LIST)
  209. {
  210. Quality[QS_BEST] = QS_BEST;
  211. iParamCount++;
  212. }
  213. if (iParamCount < MIN_QUALITY_SETTINGS)
  214. {
  215. return TRUE;
  216. }
  217. if (pUiData->pOptItem)
  218. {
  219. pParam = PFillOutOptType(pUiData->pOptType,
  220. TVOT_3STATES,
  221. MAX_QUALITY_SETTINGS,
  222. pUiData->ci.hHeap);
  223. if (pParam == NULL)
  224. return FALSE;
  225. for (i = QS_BEST; i < QS_BEST + MAX_QUALITY_SETTINGS; i ++)
  226. {
  227. pParam->cbSize = sizeof(OPTPARAM);
  228. pParam->pData = (PWSTR)ULongToPtr(IDS_QUALITY_FIRST + i);
  229. pParam->IconID = IDI_USE_DEFAULT;
  230. pParam++;
  231. }
  232. // Look for the current selection in the private devmode
  233. //
  234. if (pUiData->ci.pdm->dmDitherType & DM_DITHERTYPE &&
  235. pUiData->ci.pdm->dmDitherType >= QUALITY_MACRO_START &&
  236. pUiData->ci.pdm->dmDitherType < QUALITY_MACRO_END)
  237. {
  238. iSelection = pUiData->ci.pdm->dmDitherType;
  239. }
  240. else if (Quality[pUiData->ci.pdmPrivate->iQuality] < 0)
  241. iSelection = pUiData->ci.pUIInfo->defaultQuality;
  242. else
  243. iSelection = pUiData->ci.pdmPrivate->iQuality;
  244. //
  245. // Fill out OPTITEM, OPTTYPE, and OPTPARAM structures
  246. //
  247. pExtCheckbox = HEAPALLOC(pUiData->ci.hHeap, sizeof(EXTCHKBOX));
  248. if (pExtCheckbox == NULL)
  249. {
  250. ERR(("Memory allocation failed\n"));
  251. return FALSE;
  252. }
  253. pExtCheckbox->cbSize = sizeof(EXTCHKBOX);
  254. pExtCheckbox->Flags = ECBF_CHECKNAME_ONLY;
  255. pExtCheckbox->pTitle = (PWSTR) IDS_QUALITY_CUSTOM;
  256. pExtCheckbox->pSeparator = NULL;
  257. pExtCheckbox->pCheckedName = (PWSTR) IDS_QUALITY_CUSTOM;
  258. pExtCheckbox->IconID = IDI_CPSUI_GENERIC_ITEM;
  259. pUiData->pOptItem->pExtChkBox = pExtCheckbox;
  260. if (pUiData->ci.pdmPrivate->dwFlags & DXF_CUSTOM_QUALITY)
  261. pUiData->pOptItem->Flags |= OPTIF_ECB_CHECKED;
  262. FILLOPTITEM(pUiData->pOptItem,
  263. pUiData->pOptType,
  264. ULongToPtr(IDS_QUALITY_SETTINGS),
  265. IntToPtr(iSelection),
  266. TVITEM_LEVEL1,
  267. DMPUB_QUALITY,
  268. QUALITY_SETTINGS_ITEM,
  269. HELP_INDEX_QUALITY_SETTINGS);
  270. pUiData->pOptItem++;
  271. pUiData->pOptType++;
  272. }
  273. pUiData->dwOptItem++;
  274. pUiData->dwOptType++;
  275. #endif // !WINNT_40
  276. return TRUE;
  277. }
  278. BOOL
  279. BPackSoftFontFeature(
  280. IN OUT PUIDATA pUiData
  281. )
  282. /*++
  283. Routine Description:
  284. Pack Quality Macro feature
  285. Arguments:
  286. pUiData - Points to UIDATA structure
  287. Return Value:
  288. TRUE for success and FALSE for failure
  289. --*/
  290. {
  291. PUIINFO pUIInfo = pUiData->ci.pUIInfo;
  292. PGPDDRIVERINFO pDriverInfo;
  293. POPTPARAM pParam;
  294. PWSTR pwstr = NULL;
  295. DWORD dwType, dwSize, dwFontFormat;
  296. OEMFONTINSTPARAM fip;
  297. pDriverInfo = OFFSET_TO_POINTER(pUiData->ci.pInfoHeader,
  298. pUiData->ci.pInfoHeader->loDriverOffset);
  299. ASSERT(pDriverInfo != NULL);
  300. //
  301. // If the model doesn't support download softfont. we don't add the feature
  302. //
  303. dwFontFormat = pDriverInfo->Globals.fontformat;
  304. if (!(dwFontFormat == FF_HPPCL || dwFontFormat == FF_HPPCL_OUTLINE || dwFontFormat == FF_HPPCL_RES))
  305. return TRUE;
  306. //
  307. // If there is an exe based font installer, we don't add
  308. // this feature
  309. //
  310. dwSize = 0;
  311. if (GetPrinterData(pUiData->ci.hPrinter, REGVAL_EXEFONTINSTALLER, &dwType, NULL, dwSize, &dwSize) == ERROR_MORE_DATA)
  312. return TRUE;
  313. if (pUiData->pOptItem)
  314. {
  315. PFN_OEMFontInstallerDlgProc pDlgProc = NULL;
  316. pParam = PFillOutOptType(pUiData->pOptType,
  317. TVOT_PUSHBUTTON,
  318. 1,
  319. pUiData->ci.hHeap);
  320. if (pParam == NULL)
  321. return FALSE;
  322. //
  323. // Get the String for Soft Fonts
  324. //
  325. FOREACH_OEMPLUGIN_LOOP(&pUiData->ci)
  326. memset(&fip, 0, sizeof(OEMFONTINSTPARAM));
  327. fip.cbSize = sizeof(OEMFONTINSTPARAM);
  328. fip.hPrinter = pUiData->ci.hPrinter;
  329. fip.hModule = ghInstance;
  330. fip.hHeap = pUiData->ci.hHeap;
  331. if (HAS_COM_INTERFACE(pOemEntry))
  332. {
  333. if (HComOEMFontInstallerDlgProc(pOemEntry,
  334. NULL,
  335. 0,
  336. 0,
  337. (LPARAM)&fip) == E_NOTIMPL)
  338. continue;
  339. pwstr = fip.pFontInstallerName;
  340. break;
  341. }
  342. else
  343. {
  344. if (pDlgProc = GET_OEM_ENTRYPOINT(pOemEntry, OEMFontInstallerDlgProc))
  345. {
  346. (*pDlgProc)(NULL, 0, 0, (LPARAM)&fip);
  347. pwstr = fip.pFontInstallerName;
  348. break;
  349. }
  350. }
  351. END_OEMPLUGIN_LOOP
  352. //
  353. // If that didn't work out, put our string
  354. //
  355. if (!pwstr)
  356. {
  357. //
  358. // LoadString's 4th parameter is the max. number of characters to load,
  359. // so make sure we allocate enough bytes here.
  360. //
  361. if (!(pwstr = HEAPALLOC(pUiData->ci.hHeap, MAX_DISPLAY_NAME * sizeof(WCHAR))))
  362. {
  363. return FALSE;
  364. }
  365. if (!LoadString(ghInstance, IDS_PP_SOFTFONTS, pwstr, MAX_DISPLAY_NAME))
  366. {
  367. WARNING(("Soft Font string not found in Unidrv\n"));
  368. StringCchCopyW(pwstr, MAX_DISPLAY_NAME, L"Soft Fonts");
  369. }
  370. }
  371. pParam->cbSize = sizeof(OPTPARAM);
  372. pParam->Style = PUSHBUTTON_TYPE_CALLBACK;
  373. //
  374. // Fill out OPTITEM, OPTTYPE, and OPTPARAM structures
  375. //
  376. FILLOPTITEM(pUiData->pOptItem,
  377. pUiData->pOptType,
  378. pwstr,
  379. NULL,
  380. TVITEM_LEVEL1,
  381. DMPUB_NONE,
  382. SOFTFONT_SETTINGS_ITEM,
  383. HELP_INDEX_SOFTFONT_SETTINGS);
  384. pUiData->pOptItem++;
  385. pUiData->pOptType++;
  386. }
  387. pUiData->dwOptItem++;
  388. pUiData->dwOptType++;
  389. return TRUE;
  390. }
  391. BOOL
  392. _BPackDocumentOptions(
  393. IN OUT PUIDATA pUiData
  394. )
  395. /*++
  396. Routine Description:
  397. Pack Unidrv specific options such are enabling Print text as graphics etc
  398. Arguments:
  399. pUiData - Points to UIDATA structure
  400. Return Value:
  401. TRUE for success and FALSE for failure
  402. Note:
  403. --*/
  404. {
  405. static CONST WORD ItemInfoTxtAsGrx[] =
  406. {
  407. IDS_TEXT_ASGRX, TVITEM_LEVEL1, DMPUB_NONE,
  408. TEXT_ASGRX_ITEM, HELP_INDEX_TEXTASGRX,
  409. 2, TVOT_2STATES,
  410. IDS_ENABLED, IDI_CPSUI_ON,
  411. IDS_DISABLED, IDI_CPSUI_OFF,
  412. ITEM_INFO_SIGNATURE
  413. };
  414. PUNIDRVEXTRA pdmPrivate;
  415. DWORD dwSelTxt;
  416. BOOL bDisplayTxtAsGrx;
  417. GPDDRIVERINFO *pDriverInfo;
  418. pDriverInfo = OFFSET_TO_POINTER(pUiData->ci.pInfoHeader,
  419. pUiData->ci.pInfoHeader->loDriverOffset);
  420. ASSERT(pDriverInfo != NULL);
  421. bDisplayTxtAsGrx = ((pUiData->ci.pUIInfo->dwFlags &
  422. (FLAG_FONT_DEVICE | FLAG_FONT_DOWNLOADABLE)) &&
  423. (pDriverInfo->Globals.printertype != PT_TTY));
  424. pdmPrivate = pUiData->ci.pdmPrivate;
  425. dwSelTxt = (pdmPrivate->dwFlags & DXF_TEXTASGRAPHICS) ? 1 : 0;
  426. return (BPackColorModeFeature(pUiData) &&
  427. BPackQualityFeature(pUiData) &&
  428. BPackHalftoneFeature(pUiData) &&
  429. (bDisplayTxtAsGrx ?
  430. BPackOptItemTemplate(pUiData, ItemInfoTxtAsGrx, dwSelTxt, NULL):TRUE));
  431. }
  432. VOID
  433. _VUnpackDocumentOptions(
  434. POPTITEM pOptItem,
  435. PDEVMODE pdm
  436. )
  437. /*++
  438. Routine Description:
  439. Extract Unidrv devmode information from an OPTITEM
  440. Stored it back into Unidrv devmode.
  441. Arguments:
  442. pOptItem - Pointer to an array of OPTITEMs
  443. pdm - Pointer to a DEVMODE structure
  444. Return Value:
  445. None
  446. --*/
  447. {
  448. PUNIDRVEXTRA pdmPrivate;
  449. pdmPrivate = (PUNIDRVEXTRA) GET_DRIVER_PRIVATE_DEVMODE(pdm);
  450. switch (GETUSERDATAITEM(pOptItem->UserData))
  451. {
  452. case TEXT_ASGRX_ITEM:
  453. if (pOptItem->Sel == 1)
  454. pdmPrivate->dwFlags |= DXF_TEXTASGRAPHICS;
  455. else
  456. pdmPrivate->dwFlags &= ~DXF_TEXTASGRAPHICS;
  457. break;
  458. case QUALITY_SETTINGS_ITEM:
  459. if (pOptItem->Flags & OPTIF_ECB_CHECKED)
  460. {
  461. pdmPrivate->dwFlags |= DXF_CUSTOM_QUALITY;
  462. pdm->dmDitherType = QUALITY_MACRO_CUSTOM;
  463. }
  464. else
  465. {
  466. pdmPrivate->dwFlags &= ~DXF_CUSTOM_QUALITY;
  467. pdm->dmDitherType = QUALITY_MACRO_START + pOptItem->Sel;
  468. }
  469. pdm->dmFields |= DM_DITHERTYPE;
  470. pdmPrivate->iQuality = pOptItem->Sel;
  471. }
  472. }
  473. BOOL
  474. BPackFontCartsOptions(
  475. IN OUT PUIDATA pUiData
  476. )
  477. /*++
  478. Routine Description:
  479. Pack Font Cartridge options
  480. Arguments:
  481. pUiData - Points to UIDATA structure
  482. Return Value:
  483. TRUE for success and FALSE for failure
  484. --*/
  485. {
  486. PUIINFO pUIInfo = pUiData->ci.pUIInfo;
  487. DWORD dwFontSlot, dwFontCartsAvailable, dwExtCartsAvailable, dwSize = 0;
  488. INT iSelection = -1;
  489. POPTPARAM pParam;
  490. PWSTR pwstrCurrentSelection, pwstrEndSelection, pwstrExtCartNames;
  491. VERBOSE(("\nUniPackFontCartsOptions:pUIInfo->dwCartridgeSlotCount = %d\n",pUIInfo->dwCartridgeSlotCount));
  492. if (pUIInfo->dwCartridgeSlotCount == 0)
  493. return TRUE;
  494. VPackOptItemGroupHeader(pUiData, IDS_CPSUI_INSTFONTCART,
  495. IDI_CPSUI_FONTCARTHDR, HELP_INDEX_FONTSLOT_TYPE);
  496. if (pUiData->pOptItem)
  497. {
  498. PFONTCART pFontCarts;
  499. //
  500. // Get the current selections for the slots from registry
  501. // Read the list of font cartridge selections out of registry
  502. //
  503. pwstrCurrentSelection = PwstrGetFontCartSelections(pUiData->ci.hPrinter, pUiData->ci.hHeap, &dwSize);
  504. pwstrEndSelection = pwstrCurrentSelection + (dwSize/2);
  505. pFontCarts = OFFSET_TO_POINTER( pUIInfo->pubResourceData,
  506. pUIInfo->CartridgeSlot.loOffset );
  507. ASSERT(pFontCarts);
  508. //
  509. // Save the slot count and OPTITEM for slots for unpacking later
  510. //
  511. pUiData->dwFontCart = pUIInfo->dwCartridgeSlotCount;
  512. pUiData->pFontCart = pUiData->pOptItem;
  513. for (dwFontSlot = 0; dwFontSlot < pUIInfo->dwCartridgeSlotCount; dwFontSlot++)
  514. {
  515. //
  516. // We'll distinguish between driver built in font cartridges and external
  517. // font cartridges. dwFontCartsAvailable refers to the count of built
  518. // in driver cartridges. To this we need to add any external cartridges.
  519. //
  520. dwFontCartsAvailable = pUIInfo->CartridgeSlot.dwCount;
  521. dwExtCartsAvailable = DwGetExternalCartridges(pUiData->ci.hPrinter, pUiData->ci.hHeap, &pwstrExtCartNames);
  522. //
  523. // Build a list of OPTPARAM
  524. //
  525. pParam = PFillOutOptType(pUiData->pOptType,
  526. TVOT_LISTBOX,
  527. (WORD)(dwFontCartsAvailable + dwExtCartsAvailable),
  528. pUiData->ci.hHeap);
  529. pUiData->pOptType->Style |= OTS_LBCB_INCL_ITEM_NONE;
  530. if (pParam == NULL)
  531. return FALSE;
  532. while (dwFontCartsAvailable)
  533. {
  534. pParam->cbSize = sizeof(OPTPARAM);
  535. pParam->pData = PwstrGetFontCartName(
  536. &pUiData->ci,
  537. pUIInfo,
  538. pFontCarts,
  539. pUIInfo->CartridgeSlot.dwCount - dwFontCartsAvailable,
  540. pUiData->ci.hHeap);
  541. pParam->IconID = IDI_CPSUI_FONTCART;
  542. dwFontCartsAvailable--;
  543. pParam++;
  544. }
  545. while (dwExtCartsAvailable)
  546. {
  547. pParam->cbSize = sizeof(OPTPARAM);
  548. pParam->pData = pwstrExtCartNames;
  549. pParam->IconID = IDI_CPSUI_FONTCART;
  550. dwExtCartsAvailable--;
  551. pwstrExtCartNames += wcslen(pwstrExtCartNames);
  552. pwstrExtCartNames++;
  553. pParam++;
  554. }
  555. //
  556. // Look for the current selection in the font cart table
  557. //
  558. if (pwstrCurrentSelection)
  559. iSelection = IGetCurrentFontCartIndex(pUiData->pOptType,
  560. pwstrCurrentSelection);
  561. //
  562. // Fill out OPTITEM, OPTTYPE, and OPTPARAM structures
  563. //
  564. FILLOPTITEM(pUiData->pOptItem,
  565. pUiData->pOptType,
  566. ULongToPtr(IDS_CPSUI_SLOT1 + dwFontSlot),
  567. IntToPtr(iSelection),
  568. TVITEM_LEVEL2,
  569. DMPUB_NONE,
  570. (ULONG_PTR)FONTSLOT_ITEM,
  571. HELP_INDEX_FONTSLOT_TYPE);
  572. if (pwstrCurrentSelection && pwstrCurrentSelection < pwstrEndSelection)
  573. {
  574. pwstrCurrentSelection += wcslen(pwstrCurrentSelection);
  575. pwstrCurrentSelection++;
  576. }
  577. pUiData->pOptItem++;
  578. pUiData->pOptType++;
  579. }
  580. }
  581. pUiData->dwOptItem += pUIInfo->dwCartridgeSlotCount;
  582. pUiData->dwOptType += pUIInfo->dwCartridgeSlotCount;
  583. return TRUE;
  584. }
  585. BOOL
  586. BPackPageProtection(
  587. IN OUT PUIDATA pUiData
  588. )
  589. /*++
  590. Routine Description:
  591. Pack the page protection feature
  592. Arguments:
  593. pUiData - Points to UIDATA structure
  594. Return Value:
  595. TRUE for success and FALSE for failure
  596. --*/
  597. {
  598. return BPackItemPrinterFeature(
  599. pUiData,
  600. GET_PREDEFINED_FEATURE(pUiData->ci.pUIInfo, GID_PAGEPROTECTION),
  601. TVITEM_LEVEL1,
  602. DMPUB_NONE,
  603. (ULONG_PTR)PAGE_PROTECT_ITEM,
  604. HELP_INDEX_PAGE_PROTECT);
  605. }
  606. BOOL
  607. BPackHalftoneSetup(
  608. IN OUT PUIDATA pUiData
  609. )
  610. /*++
  611. Routine Description:
  612. Do nothing, serves as common stubs
  613. Arguments:
  614. pUiData - Points to UIDATA structure
  615. Return Value:
  616. TRUE for success and FALSE for failure
  617. --*/
  618. {
  619. // DCR - not implemented
  620. return TRUE;
  621. }
  622. BOOL
  623. _BPackPrinterOptions(
  624. IN OUT PUIDATA pUiData
  625. )
  626. /*++
  627. Routine Description:
  628. Pack driver-specific options (printer-sticky)
  629. Arguments:
  630. pUiData - Points to a UIDATA structure
  631. Return Value:
  632. TRUE for success and FALSE for failure
  633. --*/
  634. {
  635. return BPackHalftoneSetup(pUiData) &&
  636. BPackFontCartsOptions(pUiData) &&
  637. BPackPageProtection(pUiData) &&
  638. BPackSoftFontFeature(pUiData);
  639. }
  640. PWSTR
  641. PwstrGetFontCartSelections(
  642. HANDLE hPrinter,
  643. HANDLE hHeap,
  644. PDWORD pdwSize
  645. )
  646. /*++
  647. Routine Description:
  648. Read the font cart selections for the slots from the registry
  649. Arguments:
  650. hPrinter - Handle to printer instance
  651. hHeap - Handle to UI heap
  652. pdwSize - Pointer to DWORD to hold the size of the MULTI_SZ
  653. Return Value:
  654. Pointer to a MULTI-SZ containing the selections for the slots
  655. --*/
  656. {
  657. PWSTR pwstrData, pFontCartSelections = NULL;
  658. DWORD dwSize;
  659. pwstrData = PtstrGetFontCart(hPrinter, &dwSize);
  660. if (pwstrData == NULL || !BVerifyMultiSZ(pwstrData, dwSize))
  661. {
  662. MemFree(pwstrData);
  663. return NULL;
  664. }
  665. if (pFontCartSelections = HEAPALLOC(hHeap, dwSize))
  666. {
  667. CopyMemory(pFontCartSelections, pwstrData, dwSize);
  668. }
  669. MemFree(pwstrData);
  670. if (pdwSize)
  671. *pdwSize = dwSize;
  672. return pFontCartSelections;
  673. }
  674. PWSTR
  675. PwstrGetFontCartName(
  676. PCOMMONINFO pci,
  677. PUIINFO pUIInfo,
  678. FONTCART *pFontCarts,
  679. DWORD dwIndex,
  680. HANDLE hHeap
  681. )
  682. /*++
  683. Routine Description:
  684. Get the font cart name associated with the index.
  685. Arguments:
  686. pci - Pointer to COMMONINFO
  687. pUIInfo - Pointer to UIINFO
  688. pFontCarts - Pointer to array of FONTCART for the slot
  689. dwIndex - Index of font cart
  690. hHeap - Handle to Heap
  691. Return Value:
  692. Pointer to the Font Cart Name
  693. --*/
  694. {
  695. DWORD dwLen;
  696. PWSTR pwstrFontCartName;
  697. WCHAR awchBuf[MAX_DISPLAY_NAME];
  698. pFontCarts += dwIndex;
  699. pwstrFontCartName = (PWSTR)OFFSET_TO_POINTER(pUIInfo->pubResourceData,
  700. pFontCarts->strCartName.loOffset);
  701. if (!pwstrFontCartName)
  702. {
  703. if (! BPrepareForLoadingResource(pci, TRUE))
  704. return NULL;
  705. dwLen = ILOADSTRING(pci, pFontCarts->dwRCCartNameID,
  706. awchBuf, MAX_DISPLAY_NAME);
  707. pwstrFontCartName = HEAPALLOC(pci->hHeap, (dwLen+1) * sizeof(WCHAR));
  708. if (pwstrFontCartName == NULL)
  709. {
  710. ERR(("Memory allocation failed\n"));
  711. return NULL;
  712. }
  713. //
  714. // Copy the string to allocated memory and
  715. // return a pointer to it.
  716. //
  717. CopyMemory(pwstrFontCartName, awchBuf, dwLen*sizeof(WCHAR));
  718. return pwstrFontCartName;
  719. }
  720. else
  721. return pwstrFontCartName;
  722. }
  723. INT
  724. IGetCurrentFontCartIndex(
  725. POPTTYPE pOptType,
  726. PWSTR pCurrentSelection
  727. )
  728. /*++
  729. Routine Description:
  730. Find the matching font cart
  731. Arguments:
  732. pOptType - Pointer to OPTTYPE containing the font carts options
  733. pCurrentSelection - The name of the cartridge selection for the slot
  734. Return Value:
  735. Index to the options list
  736. --*/
  737. {
  738. INT iIndex;
  739. POPTPARAM pParam = pOptType->pOptParam;
  740. for (iIndex = 0 ; iIndex < pOptType->Count; iIndex++)
  741. {
  742. if (wcscmp(pCurrentSelection, pParam->pData) == EQUAL_STRING)
  743. return iIndex;
  744. pParam++;
  745. }
  746. return -1;
  747. }
  748. DWORD
  749. DwCollectFontCart(
  750. PUIDATA pUiData,
  751. PWSTR pwstrTable,
  752. DWORD cbSize
  753. )
  754. /*++
  755. Routine Description:
  756. Collect Font Cart assignment information
  757. Arguments:
  758. pUiData - Pointer to our UIDATA structure
  759. pwstrTable - Pointer to memory buffer for storing the table
  760. (NULL if the caller is only interested in the table size)
  761. cbSize - size (in bytes) of the pwstrTable memory buffer
  762. (0 if pwstrTable is NULL)
  763. Return Value:
  764. Size of the table bytes. 0 if there is an error.
  765. --*/
  766. {
  767. DWORD dwChars = 0;
  768. LONG lLength = 0;
  769. DWORD dwIndex;
  770. POPTPARAM pOptParam;
  771. DWORD dwOptItem = pUiData->dwFontCart;
  772. POPTITEM pOptItem = pUiData->pFontCart;
  773. for (dwIndex=0; dwIndex < dwOptItem; dwIndex++, pOptItem++)
  774. {
  775. if (pOptItem->Flags & OPTIF_DISABLED)
  776. continue;
  777. //
  778. // Get the Font Cart name for each slot (dwIndex)
  779. //
  780. if (pOptItem->Sel == -1)
  781. {
  782. lLength = wcslen(L"Not Available") + 1;
  783. }
  784. else
  785. {
  786. pOptParam = pOptItem->pOptType->pOptParam + pOptItem->Sel;
  787. lLength = wcslen(pOptParam->pData) + 1;
  788. }
  789. dwChars += lLength;
  790. if (pwstrTable != NULL)
  791. {
  792. if (pOptItem->Sel == -1)
  793. StringCchCopyW(pwstrTable, cbSize / sizeof(WCHAR), L"Not Available");
  794. else
  795. StringCchCopyW(pwstrTable, cbSize / sizeof(WCHAR), pOptParam->pData);
  796. pwstrTable += lLength;
  797. }
  798. }
  799. //
  800. // Append a NUL character at the end of the table
  801. //
  802. dwChars++;
  803. if (pwstrTable != NULL)
  804. *pwstrTable = NUL;
  805. //
  806. // Return the table size in bytes
  807. //
  808. return (dwChars * sizeof(WCHAR));
  809. }
  810. BOOL
  811. BUnPackFontCart(
  812. PUIDATA pUiData
  813. )
  814. /*++
  815. Routine Description:
  816. Save the Font Cart selection into registry
  817. Arguments:
  818. pUiData - Pointer to UIDATA
  819. Return Value:
  820. TRUE for success and FALSE for failure
  821. Note:
  822. --*/
  823. {
  824. PFN_OEMUpdateExternalFonts pUpdateProc = NULL;
  825. PWSTR pwstrTable;
  826. DWORD dwTableSize;
  827. BOOL bHasOEMUpdateFn = FALSE;
  828. //
  829. // Figure out how much memory we need to store
  830. // the Font Cart table
  831. //
  832. dwTableSize = DwCollectFontCart(pUiData, NULL, 0);
  833. if (dwTableSize == 0 || (pwstrTable = MemAllocZ(dwTableSize)) == NULL)
  834. {
  835. ERR(("DwCollectFontCart/MemAlloc"));
  836. return FALSE;
  837. }
  838. //
  839. // Assemble the font cartridge table to be saved in registry
  840. //
  841. if (dwTableSize != DwCollectFontCart(pUiData, pwstrTable, dwTableSize))
  842. {
  843. ERR(("CollectFontCart"));
  844. MemFree(pwstrTable);
  845. return FALSE;
  846. }
  847. //
  848. // Save the font cart information to registry
  849. //
  850. if (! BSaveFontCart(pUiData->ci.hPrinter, pwstrTable))
  851. {
  852. ERR(("SaveFontCart"));
  853. }
  854. //
  855. // Inform font installer (if present) about font cartridge selection change
  856. //
  857. FOREACH_OEMPLUGIN_LOOP(&pUiData->ci)
  858. if (HAS_COM_INTERFACE(pOemEntry))
  859. {
  860. if (HComOEMUpdateExternalFonts(pOemEntry,
  861. pUiData->ci.hPrinter,
  862. pUiData->ci.hHeap,
  863. pwstrTable) == E_NOTIMPL)
  864. continue;
  865. bHasOEMUpdateFn = TRUE;
  866. break;
  867. }
  868. else
  869. {
  870. pUpdateProc = GET_OEM_ENTRYPOINT(pOemEntry, OEMUpdateExternalFonts);
  871. if (pUpdateProc)
  872. {
  873. bHasOEMUpdateFn = TRUE;
  874. pUpdateProc(pUiData->ci.hPrinter, pUiData->ci.hHeap, pwstrTable);
  875. break;
  876. }
  877. }
  878. END_OEMPLUGIN_LOOP
  879. if (!bHasOEMUpdateFn)
  880. {
  881. //
  882. // No OEM Dll wants to handle this, we'll handle it ourselves
  883. //
  884. BUpdateExternalFonts(pUiData->ci.hPrinter, pUiData->ci.hHeap, pwstrTable);
  885. }
  886. MemFree(pwstrTable);
  887. return TRUE;
  888. }
  889. DWORD
  890. DwGetExternalCartridges(
  891. IN HANDLE hPrinter,
  892. IN HANDLE hHeap,
  893. OUT PWSTR *ppwstrExtCartNames
  894. )
  895. {
  896. PWSTR pwstrData;
  897. DWORD dwSize;
  898. *ppwstrExtCartNames = NULL;
  899. pwstrData = PtstrGetPrinterDataString(hPrinter, REGVAL_EXTFONTCART, &dwSize);
  900. if (pwstrData == NULL || !BVerifyMultiSZ(pwstrData, dwSize))
  901. {
  902. MemFree(pwstrData);
  903. return 0;
  904. }
  905. if (*ppwstrExtCartNames = HEAPALLOC(hHeap, dwSize))
  906. {
  907. CopyMemory(*ppwstrExtCartNames, pwstrData, dwSize);
  908. }
  909. MemFree(pwstrData);
  910. return DwCountStringsInMultiSZ(*ppwstrExtCartNames);
  911. }
  912. BOOL
  913. BUnpackHalftoneSetup(
  914. IN OUT PUIDATA pUiData
  915. )
  916. /*++
  917. Routine Description:
  918. Unpack halftone setup information
  919. Arguments:
  920. pUiData - Points to a UIDATA structure
  921. Return Value:
  922. TRUE for success and FALSE for failure
  923. --*/
  924. {
  925. // DCR - not implemented
  926. return TRUE;
  927. }
  928. BOOL
  929. _BUnpackPrinterOptions(
  930. IN OUT PUIDATA pUiData
  931. )
  932. /*++
  933. Routine Description:
  934. Unpack driver-specific options (printer-sticky)
  935. Arguments:
  936. pUiData - Points to a UIDATA structure
  937. Return Value:
  938. TRUE for success and FALSE for failure
  939. --*/
  940. {
  941. return BUnpackHalftoneSetup(pUiData) &&
  942. BUnPackFontCart(pUiData);
  943. }
  944. //
  945. // Data structures and functions for enumerating printer device fonts
  946. //
  947. typedef struct _ENUMDEVFONT {
  948. INT iBufSize;
  949. INT iCurSize;
  950. PWSTR pwstrBuf;
  951. } ENUMDEVFONT, *PENUMDEVFONT;
  952. INT CALLBACK
  953. EnumDevFontProc(
  954. ENUMLOGFONT *pelf,
  955. NEWTEXTMETRIC *pntm,
  956. INT FontType,
  957. LPARAM lParam
  958. )
  959. {
  960. PENUMDEVFONT pEnumData;
  961. PWSTR pFamilyName;
  962. INT iSize;
  963. //
  964. // We only care about printer device fonts.
  965. //
  966. if (!(FontType & DEVICE_FONTTYPE))
  967. return 1;
  968. //
  969. // For app compatibility, GDI sets FontType to be DEVICE_FONTTYPE
  970. // even for PS OpenType fonts and Type1 fonts. So we also need to
  971. // filter them out using Win2K+ only GDI flags.
  972. //
  973. #ifndef WINNT_40
  974. if ((pntm->ntmFlags & NTM_PS_OPENTYPE) ||
  975. (pntm->ntmFlags & NTM_TYPE1))
  976. return 1;
  977. #endif // WINNT_40
  978. pEnumData = (PENUMDEVFONT) lParam;
  979. pFamilyName = pelf->elfLogFont.lfFaceName;
  980. iSize = SIZE_OF_STRING(pFamilyName);
  981. pEnumData->iCurSize += iSize;
  982. if (pEnumData->pwstrBuf == NULL)
  983. {
  984. //
  985. // Calculating output buffer size only
  986. //
  987. }
  988. else if (pEnumData->iCurSize >= pEnumData->iBufSize)
  989. {
  990. //
  991. // Output buffer is too small
  992. //
  993. return 0;
  994. }
  995. else
  996. {
  997. CopyMemory(pEnumData->pwstrBuf, pFamilyName, iSize);
  998. pEnumData->pwstrBuf = (PWSTR) ((PBYTE) pEnumData->pwstrBuf + iSize);
  999. }
  1000. return 1;
  1001. }
  1002. INT
  1003. _IListDevFontNames(
  1004. HDC hdc,
  1005. PWSTR pwstrBuf,
  1006. INT iSize
  1007. )
  1008. {
  1009. INT iOldMode;
  1010. ENUMDEVFONT EnumData;
  1011. EnumData.iBufSize = iSize;
  1012. EnumData.pwstrBuf = pwstrBuf;
  1013. EnumData.iCurSize = 0;
  1014. //
  1015. // Enumerate device fonts
  1016. //
  1017. iOldMode = SetGraphicsMode(hdc, GM_ADVANCED);
  1018. if (! EnumFontFamilies(
  1019. hdc,
  1020. NULL,
  1021. (FONTENUMPROC) EnumDevFontProc,
  1022. (LPARAM) &EnumData))
  1023. {
  1024. return 0;
  1025. }
  1026. SetGraphicsMode(hdc, iOldMode);
  1027. //
  1028. // Remember the list of device font names is in MULTI_SZ format;
  1029. // Take the last NUL terminator into consideration
  1030. //
  1031. EnumData.iCurSize += sizeof(WCHAR);
  1032. if (EnumData.pwstrBuf)
  1033. *(EnumData.pwstrBuf) = NUL;
  1034. return EnumData.iCurSize;
  1035. }
  1036. //
  1037. // Determine whether the printer supports stapling
  1038. //
  1039. BOOL
  1040. _BSupportStapling(
  1041. PCOMMONINFO pci
  1042. )
  1043. {
  1044. DWORD dwIndex;
  1045. return (PGetNamedFeature(pci->pUIInfo, "Stapling", &dwIndex) &&
  1046. !_BFeatureDisabled(pci, dwIndex, GID_UNKNOWN));
  1047. }
  1048. INT_PTR CALLBACK
  1049. _AboutDlgProc(
  1050. HWND hDlg,
  1051. UINT message,
  1052. WPARAM wParam,
  1053. LPARAM lParam
  1054. )
  1055. /*++
  1056. Routine Description:
  1057. Dlg Proc for About button
  1058. Arguments:
  1059. hDlg - Identifies the property sheet page
  1060. message - Specifies the message
  1061. wParam - Specifies additional message-specific information
  1062. lParam - Specifies additional message-specific information
  1063. Return Value:
  1064. Depends on the value of message parameter
  1065. --*/
  1066. {
  1067. PUIDATA pUiData;
  1068. PWSTR pGpdFilename;
  1069. PGPDDRIVERINFO pDriverInfo;
  1070. switch (message)
  1071. {
  1072. case WM_INITDIALOG:
  1073. //
  1074. // Initialize the About dialog box
  1075. //
  1076. pUiData = (PUIDATA) lParam;
  1077. ASSERT(VALIDUIDATA(pUiData));
  1078. #ifdef WINNT_40
  1079. SetDlgItemTextA(hDlg, IDC_WINNT_VER, "Version " VER_54DRIVERVERSION_STR);
  1080. #else
  1081. SetDlgItemTextA(hDlg, IDC_WINNT_VER, "Version " VER_PRODUCTVERSION_STR);
  1082. #endif // WINNT_40
  1083. SetDlgItemText(hDlg, IDC_MODELNAME, pUiData->ci.pDriverInfo3->pName);
  1084. pDriverInfo = OFFSET_TO_POINTER(pUiData->ci.pInfoHeader, pUiData->ci.pInfoHeader->loDriverOffset);
  1085. ASSERT(pDriverInfo != NULL);
  1086. if (pDriverInfo->Globals.pwstrGPDFileName)
  1087. SetDlgItemText(hDlg, IDC_GPD_FILENAME, pDriverInfo->Globals.pwstrGPDFileName);
  1088. else
  1089. SetDlgItemText(hDlg, IDC_GPD_FILENAME, L"Not Available");
  1090. if (pDriverInfo->Globals.pwstrGPDFileVersion)
  1091. SetDlgItemTextA(hDlg, IDC_GPD_FILEVER, (PSTR)pDriverInfo->Globals.pwstrGPDFileVersion);
  1092. else
  1093. SetDlgItemText(hDlg, IDC_GPD_FILEVER, L"Not Available");
  1094. return TRUE;
  1095. case WM_COMMAND:
  1096. switch (LOWORD(wParam))
  1097. {
  1098. case IDOK:
  1099. case IDCANCEL:
  1100. EndDialog(hDlg, LOWORD(wParam));
  1101. return TRUE;
  1102. }
  1103. break;
  1104. }
  1105. return FALSE;
  1106. }
  1107. BOOL
  1108. BFoundInDisabledList(
  1109. IN PGPDDRIVERINFO pDriverInfo,
  1110. IN POPTION pOption,
  1111. IN DWORD dwFeatureID
  1112. )
  1113. /*++
  1114. Routine Description:
  1115. Determines whether the feature indicated by dwFeatureID is found in the
  1116. pOption->liDisabledFeatureList.
  1117. Arguments:
  1118. Return Value:
  1119. TRUE for disabled feature, otherwise FALSE
  1120. --*/
  1121. {
  1122. PLISTNODE pListNode;
  1123. pListNode = LISTNODEPTR(pDriverInfo, pOption->liDisabledFeatures);
  1124. while (pListNode)
  1125. {
  1126. if ( ((PQUALNAME)(&pListNode->dwData))->wFeatureID == (WORD)dwFeatureID)
  1127. {
  1128. return TRUE;
  1129. }
  1130. pListNode = LISTNODEPTR(pDriverInfo, pListNode->dwNextItem);
  1131. }
  1132. return FALSE;
  1133. }
  1134. BOOL
  1135. _BFeatureDisabled(
  1136. IN PCOMMONINFO pci,
  1137. IN DWORD dwFeatureIndex,
  1138. IN WORD wGID
  1139. )
  1140. /*++
  1141. Routine Description:
  1142. Determines whether the feature indicated by wGID is disabled.
  1143. For example, a device can support collate but only if the hard disk is
  1144. installed.
  1145. Arguments:
  1146. pci - Points to COMMONINFO
  1147. wGID - GID_XXX
  1148. Return Value:
  1149. TRUE for disabled feature, otherwise FALSE
  1150. --*/
  1151. {
  1152. DWORD dwFeatureID, dwIndex, dwFeatureCount;
  1153. PFEATURE pFeatureList, pFeature = NULL;
  1154. PGPDDRIVERINFO pDriverInfo;
  1155. PUIINFO pUIInfo = pci->pUIInfo;
  1156. POPTSELECT pCombinedOptions = pci->pCombinedOptions;
  1157. BYTE ubCurOptIndex, ubNext;
  1158. POPTION pOption;
  1159. pDriverInfo = OFFSET_TO_POINTER(pUIInfo->pInfoHeader,
  1160. pUIInfo->pInfoHeader->loDriverOffset);
  1161. dwFeatureCount = pUIInfo->dwDocumentFeatures + pUIInfo->dwPrinterFeatures;
  1162. if (pDriverInfo == NULL)
  1163. return FALSE;
  1164. if (dwFeatureIndex != 0xFFFFFFFF &&
  1165. wGID == GID_UNKNOWN &&
  1166. dwFeatureIndex <= dwFeatureCount)
  1167. {
  1168. dwFeatureID = dwFeatureIndex;
  1169. }
  1170. else
  1171. {
  1172. ASSERT(wGID < MAX_GID);
  1173. if (wGID < MAX_GID)
  1174. {
  1175. pFeature = GET_PREDEFINED_FEATURE(pUIInfo, wGID);
  1176. }
  1177. else
  1178. pFeature = NULL;
  1179. if (pFeature == NULL)
  1180. return FALSE;
  1181. dwFeatureID = GET_INDEX_FROM_FEATURE(pUIInfo, pFeature);
  1182. }
  1183. if (!(pFeatureList = OFFSET_TO_POINTER(pUIInfo->pInfoHeader, pUIInfo->loFeatureList)))
  1184. return FALSE;
  1185. for (dwIndex = 0;
  1186. dwIndex < dwFeatureCount;
  1187. dwIndex++, pFeatureList++)
  1188. {
  1189. //
  1190. // Currently we only allow *DisabledFeatures to be used with PRINTER_PROPERTY features. This
  1191. // is because the UI code won't be able to refresh the document settings correctly if you have
  1192. // *DisabledFeatures on non-printer-sticky features.
  1193. //
  1194. // Example: if you put *DisabledFeatures: LIST(Collate) into a PaperSize option, then in the
  1195. // document settings select that PaperSize option, you won't see EMF features refreshed
  1196. // correctly unless you close and reopen the UI. This is because in cpcbDocumentPropertyCallback,
  1197. // we only call VUpdateEmfFeatureItems when EMF-related feature settings are changed. Changing
  1198. // PaperSize option won't trigger the calling of VUpdateEmfFeatureItems, therefore no refresh.
  1199. //
  1200. if (pFeatureList->dwFeatureType != FEATURETYPE_PRINTERPROPERTY)
  1201. continue;
  1202. ubNext = (BYTE)dwIndex;
  1203. while (1)
  1204. {
  1205. ubCurOptIndex = pCombinedOptions[ubNext].ubCurOptIndex;
  1206. pOption = PGetIndexedOption(pUIInfo, pFeatureList, ubCurOptIndex == OPTION_INDEX_ANY ? 0 : ubCurOptIndex);
  1207. if (pOption && BFoundInDisabledList(pDriverInfo, pOption, dwFeatureID))
  1208. return TRUE;
  1209. if ((ubNext = pCombinedOptions[ubNext].ubNext) == NULL_OPTSELECT)
  1210. break;
  1211. }
  1212. }
  1213. return FALSE;
  1214. }
  1215. PTSTR
  1216. PtstrUniGetDefaultTTSubstTable(
  1217. IN PCOMMONINFO pci,
  1218. IN PUIINFO pUIInfo
  1219. )
  1220. /*++
  1221. Routine Description:
  1222. Get the default font substitution table for Unidrv
  1223. Arguments:
  1224. pci - Points to COMMONINFO
  1225. pUIInfo - Points to UIINFO
  1226. Return Value:
  1227. Pointer to the font substituion table , otherwise NULL
  1228. --*/
  1229. {
  1230. #define DEFAULT_FONTSUB_SIZE (1024 * sizeof(WCHAR))
  1231. PTTFONTSUBTABLE pDefaultTTFontSub, pCopyTTFS;
  1232. PTSTR ptstrTable, ptstrTableOrg;
  1233. DWORD dwCount, dwEntrySize, dwTTFontLen, dwDevFontLen, dwBuffSize, dwAvail;
  1234. PWSTR pTTFontName, pDevFontName;
  1235. if (pUIInfo->dwFontSubCount)
  1236. {
  1237. if (!(pDefaultTTFontSub = OFFSET_TO_POINTER(pUIInfo->pubResourceData,
  1238. pUIInfo->loFontSubstTable)))
  1239. {
  1240. ERR(("Default TT font sub table from GPD Parser is NULL \n"));
  1241. return NULL;
  1242. }
  1243. dwBuffSize = sizeof(TTFONTSUBTABLE) * pUIInfo->dwFontSubCount;
  1244. if (!(pCopyTTFS = HEAPALLOC(pci->hHeap, dwBuffSize)))
  1245. {
  1246. ERR(("Fatal: unable to alloc requested memory: %d bytes.\n", dwBuffSize));
  1247. return NULL;
  1248. }
  1249. //
  1250. // Make a writable copy of the font substitution table
  1251. // if arDevFontName.dwCount is zero,
  1252. // move rcID into arDevFontName.loOffset like other
  1253. // snapshot entries and set highbit.
  1254. //
  1255. CopyMemory((PBYTE)pCopyTTFS,
  1256. (PBYTE)pDefaultTTFontSub,
  1257. dwBuffSize);
  1258. for (dwCount = 0 ; dwCount < pUIInfo->dwFontSubCount ; dwCount++)
  1259. {
  1260. if(!pCopyTTFS[dwCount].arTTFontName.dwCount)
  1261. {
  1262. pCopyTTFS[dwCount].arTTFontName.loOffset =
  1263. pCopyTTFS[dwCount].dwRcTTFontNameID | GET_RESOURCE_FROM_DLL ;
  1264. }
  1265. if(!pCopyTTFS[dwCount].arDevFontName.dwCount)
  1266. {
  1267. pCopyTTFS[dwCount].arDevFontName.loOffset =
  1268. pCopyTTFS[dwCount].dwRcDevFontNameID | GET_RESOURCE_FROM_DLL ;
  1269. }
  1270. }
  1271. dwBuffSize = dwAvail = DEFAULT_FONTSUB_SIZE;
  1272. if (!(ptstrTableOrg = ptstrTable = MemAlloc(dwBuffSize)))
  1273. {
  1274. ERR(("Fatal: unable to alloc requested memory: %d bytes.\n", dwBuffSize));
  1275. return NULL;
  1276. }
  1277. for (dwCount = 0; dwCount < pUIInfo->dwFontSubCount; dwCount++, pCopyTTFS ++)
  1278. {
  1279. pTTFontName = PGetReadOnlyDisplayName( pci,
  1280. pCopyTTFS->arTTFontName.loOffset );
  1281. pDevFontName = PGetReadOnlyDisplayName( pci,
  1282. pCopyTTFS->arDevFontName.loOffset );
  1283. if (pTTFontName == NULL || pDevFontName == NULL)
  1284. continue;
  1285. dwTTFontLen = wcslen(pTTFontName) + 1;
  1286. dwDevFontLen = wcslen( pDevFontName) + 1 ;
  1287. dwEntrySize = (dwDevFontLen + dwTTFontLen + 1) * sizeof(WCHAR);
  1288. if (dwAvail < dwEntrySize)
  1289. {
  1290. DWORD dwCurrOffset;
  1291. //
  1292. // Reallocate the Buffer
  1293. //
  1294. dwAvail = max(dwEntrySize, DEFAULT_FONTSUB_SIZE);
  1295. dwBuffSize += dwAvail;
  1296. dwCurrOffset = (DWORD)(ptstrTable - ptstrTableOrg);
  1297. if (!(ptstrTable = MemRealloc(ptstrTableOrg, dwCurrOffset * sizeof(WCHAR), dwBuffSize)))
  1298. {
  1299. ERR(("Fatal: unable to realloac requested memory: %d bytes.\n", dwBuffSize));
  1300. MemFree(ptstrTableOrg);
  1301. return NULL;
  1302. }
  1303. ptstrTableOrg = ptstrTable;
  1304. ptstrTable += dwCurrOffset;
  1305. dwAvail = dwBuffSize - dwCurrOffset*sizeof(WCHAR);
  1306. }
  1307. dwAvail -= dwEntrySize;
  1308. CopyString(ptstrTable, pTTFontName, dwTTFontLen);
  1309. ptstrTable += dwTTFontLen;
  1310. CopyString(ptstrTable, pDevFontName, dwDevFontLen);
  1311. ptstrTable += dwDevFontLen;
  1312. }
  1313. *ptstrTable = NUL;
  1314. }
  1315. else
  1316. {
  1317. ptstrTableOrg = NULL;
  1318. }
  1319. return ptstrTableOrg;
  1320. }
  1321. BOOL
  1322. BOkToChangeColorToMono(
  1323. IN PCOMMONINFO pci,
  1324. IN PDEVMODE pdm,
  1325. OUT SHORT * pPrintQuality,
  1326. OUT SHORT * pYResolution
  1327. )
  1328. /*++
  1329. Routine Description:
  1330. This function determines if the resolution can be left
  1331. unchanged when switching from Color to Mono printing.
  1332. This is implemented for switching between color and monochrome
  1333. mode within a job for performance
  1334. Arguments:
  1335. pci - Points to COMMONINFO
  1336. pdm - Points to DEVMODE
  1337. pPrintQuality, pYResolution - To contain the output resolution
  1338. pUIInfo - Points to UIINFO
  1339. Return Value:
  1340. Returns TRUE if the same resolution used to print Color
  1341. can also be used to print Mono. If true, this resolution
  1342. is placed in pptRes for the spooler to use in place of
  1343. negative values of print quality.
  1344. otherwise return FALSE and pptRes is not initialized.
  1345. --*/
  1346. {
  1347. PFEATURE pFeatureColor, pFeatureRes;
  1348. DWORD dwColorModeIndex, dwCurOption, dwResIndex, dwNewResOption, dwCurResOption ;
  1349. SHORT sXres, sYres;
  1350. POPTION pColorMode;
  1351. PCOLORMODEEX pColorModeEx;
  1352. PRESOLUTION pResOption;
  1353. PDEVMODE pDevmode, pTmpDevmode;
  1354. if ((pFeatureColor = GET_PREDEFINED_FEATURE(pci->pUIInfo, GID_COLORMODE))== NULL)
  1355. return FALSE;
  1356. dwColorModeIndex = GET_INDEX_FROM_FEATURE(pci->pUIInfo, pFeatureColor);
  1357. pColorMode = (POPTION)PGetIndexedOption(pci->pUIInfo,
  1358. pFeatureColor,
  1359. pci->pCombinedOptions[dwColorModeIndex].ubCurOptIndex);
  1360. if (pColorMode == NULL)
  1361. return FALSE;
  1362. pColorModeEx = OFFSET_TO_POINTER(
  1363. pci->pInfoHeader,
  1364. pColorMode->loRenderOffset);
  1365. if(pColorModeEx == NULL || pColorModeEx->bColor == FALSE)
  1366. return(FALSE);
  1367. if ((pFeatureRes = GET_PREDEFINED_FEATURE(pci->pUIInfo, GID_RESOLUTION)) == NULL)
  1368. return FALSE;
  1369. dwResIndex = GET_INDEX_FROM_FEATURE(pci->pUIInfo, pFeatureRes);
  1370. dwCurResOption = pci->pCombinedOptions[dwResIndex].ubCurOptIndex ;
  1371. pResOption = (PRESOLUTION)PGetIndexedOption(pci->pUIInfo,
  1372. pFeatureRes,
  1373. dwCurResOption);
  1374. if (pResOption == NULL)
  1375. return FALSE;
  1376. sXres = (SHORT)pResOption->iXdpi;
  1377. sYres = (SHORT)pResOption->iYdpi;
  1378. //
  1379. // Make a copy of the public devmode
  1380. //
  1381. if ((pDevmode = MemAllocZ(sizeof(DEVMODE))) == NULL)
  1382. return FALSE;
  1383. CopyMemory(pDevmode, pdm, sizeof(DEVMODE));
  1384. pDevmode->dmPrintQuality = sXres ;
  1385. pDevmode->dmYResolution = sYres ;
  1386. //
  1387. // Now ask to print in mono
  1388. //
  1389. pDevmode->dmColor = DMCOLOR_MONOCHROME ;
  1390. //
  1391. // This is a kludge to fix up the devmode in pci. I hope it works!
  1392. //
  1393. pTmpDevmode = pci->pdm;
  1394. pci->pdm = pDevmode;
  1395. VFixOptionsArrayWithDevmode(pci);
  1396. (VOID)ResolveUIConflicts( pci->pRawData,
  1397. pci->pCombinedOptions,
  1398. MAX_COMBINED_OPTIONS,
  1399. MODE_DOCANDPRINTER_STICKY);
  1400. pci->pdm = pTmpDevmode;
  1401. dwNewResOption = pci->pCombinedOptions[dwResIndex].ubCurOptIndex ;
  1402. if(dwNewResOption != dwCurResOption)
  1403. {
  1404. // gotta compare resolutions
  1405. if ((pResOption = (PRESOLUTION)PGetIndexedOption(pci->pUIInfo,
  1406. pFeatureRes,
  1407. dwNewResOption)) == NULL)
  1408. {
  1409. MemFree(pDevmode);
  1410. return FALSE;
  1411. }
  1412. if ((sXres != pResOption->iXdpi) || (sYres != pResOption->iYdpi))
  1413. {
  1414. MemFree(pDevmode);
  1415. return(FALSE);
  1416. }
  1417. else // Same dpi for Color and Monochrome.
  1418. {
  1419. //
  1420. // For predefined negative user defined resolution don't replace
  1421. // the values in dmPrintQuality and dmYResolution. This is needed
  1422. // because user defined print quality may map to multiple settings
  1423. // like Ink density.
  1424. //
  1425. if ( (pdm->dmFields & DM_PRINTQUALITY) &&
  1426. (pdm->dmPrintQuality >= DMRES_HIGH) &&
  1427. (pdm->dmPrintQuality <= DMRES_DRAFT) )
  1428. {
  1429. sXres = pdm->dmPrintQuality;
  1430. sYres = pdm->dmYResolution;
  1431. }
  1432. }
  1433. }
  1434. else // Same resolution for Color and Monochrome.
  1435. {
  1436. //
  1437. // For negative user defined resolution don't replace the values in
  1438. // in dmPrintQuality and dmYResolution. This is needed because user
  1439. // defined print quality may map to multiple settings like Ink density.
  1440. //
  1441. if ( (pdm->dmFields & DM_PRINTQUALITY) &&
  1442. (pdm->dmPrintQuality < DMRES_HIGH) )
  1443. {
  1444. sXres = pdm->dmPrintQuality;
  1445. sYres = pdm->dmYResolution;
  1446. }
  1447. }
  1448. dwCurOption = pci->pCombinedOptions[dwColorModeIndex].ubCurOptIndex ;
  1449. if ((pColorMode = (POPTION)PGetIndexedOption(pci->pUIInfo, pFeatureColor,dwCurOption)) == NULL ||
  1450. (pColorModeEx = OFFSET_TO_POINTER(pci->pInfoHeader, pColorMode->loRenderOffset)) == NULL ||
  1451. (pColorModeEx->bColor))
  1452. {
  1453. MemFree(pDevmode);
  1454. return FALSE;
  1455. }
  1456. if (pPrintQuality)
  1457. *pPrintQuality = sXres ;
  1458. if (pYResolution)
  1459. *pYResolution = sYres ;
  1460. //
  1461. // Free the devmode.
  1462. //
  1463. if (pDevmode)
  1464. MemFree(pDevmode);
  1465. return TRUE ;
  1466. }